home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
feel-075.lha
/
feel0.75
/
AddOns
/
eupvm.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-08
|
10KB
|
449 lines
/*
*
* PVM/Feel interface
* uses reader module...
*/
/* PVM functions:
* pvm_enroll(name)
* pvm_initiate(hosttype, name)
* pvm_leave()
* pbm_self()
* pvm_snd(id type message)
* pvm_rcv(type) -> [object, info]
* pvm_recvmulti(types) -> [object, info]
* pvm_terminate()
* status(pvm_id) -> bool
*
*/
#include <stdio.h>
#include "defs.h"
#include "structs.h"
#include "funcalls.h"
#include "global.h"
#include "error.h"
#include "allocate.h"
#include "class.h"
#include "modboot.h"
#include "bootstrap.h"
#include "allocate.h"
#include "generics.h"
#include "calls.h"
#include "obread.h"
#include "eupvm_p.h"
/* Max message size */
#define PVM_MSGBUF 16384
/* class, returned by enroll, used by snd */
#define PVM_NAME(id) (CAR(id))
#define PVM_NUMBER(id) (CDR(id))
LispObject Pvm_Id;
static LispObject make_pvm_id(LispObject *stacktop,LispObject name,int n)
{
LispObject new_id,xx;
STACK_TMP(name);
xx=allocate_integer(stacktop,n);
UNSTACK_TMP(name);
new_id = EUCALL_2(Fn_cons,name,xx);
lval_classof(new_id) = Pvm_Id;
return new_id;
}
static EUFUN_1(Fn_make_pvm_id_from_pair, pair)
{
LispObject new_ob;
if (!is_cons(pair))
CallError(stacktop,"make-id: Type error",pair,NONCONTINUABLE);
new_ob = EUCALL_2(Fn_cons,CAR(pair),CDR(pair));
lval_classof(new_ob) = Pvm_Id;
return new_ob;
}
EUFUN_CLOSE
static EUFUN_1( Fn_make_pvm_id, name)
{
return make_pvm_id(stacktop,name,-1);
}
EUFUN_CLOSE
static EUFUN_1( Fn_pvm_enroll, name)
{
int ret;
if (!is_string(name))
CallError(stacktop,"enroll: expected a string",name,NONCONTINUABLE);
if ((ret = enroll(stringof(name))) < 0)
CallError(stacktop,"enroll: call failed",name,NONCONTINUABLE);
return make_pvm_id(stacktop,name,ret);
}
EUFUN_CLOSE
/* Name is an executable in ~/pvm/<ARCH> */
/* type is a machine type, () if any will do.. */
static EUFUN_2( Fn_pvm_initiate_by_type, type, name)
{
int ret;
if(!is_string(type) || !is_string(name))
CallError(stacktop,"initiate: type error",name,NONCONTINUABLE);
if ((ret = initiate(stringof(name),stringof(type))) < 0)
CallError(stacktop,"initiate: call failed",nil,NONCONTINUABLE);
return make_pvm_id(stacktop,name,ret);
}
EUFUN_CLOSE
static EUFUN_2( Fn_pvm_initiate_by_host_name, hostname, name)
{
int ret;
if(!is_string(hostname) || !is_string(name))
CallError(stacktop,"initiate: type error",hostname,NONCONTINUABLE);
if ((ret = initiateM(stringof(name),stringof(hostname))) < 0)
CallError(stacktop,"initiate: call failed",nil,NONCONTINUABLE);
return make_pvm_id(stacktop,name,ret);
}
EUFUN_CLOSE
/* Note that this closes stdio buffers */
static EUFUN_0( Fn_pvm_leave)
{
leave();
return nil;
}
EUFUN_CLOSE
static EUFUN_1( Fn_pvm_terminate, pvm_id)
{
int ret;
if (EUCALL_2(Fn_subclassp,classof(pvm_id),Pvm_Id)==nil)
CallError(stacktop,"terminate: type error",nil,NONCONTINUABLE);
if ((ret = terminate(PVM_NAME(pvm_id),PVM_NUMBER(pvm_id))) < 0)
CallError(stacktop,"terminate: call failed",pvm_id,NONCONTINUABLE);
return nil;
}
EUFUN_CLOSE
static EUFUN_1( Fn_pvm_status, pvm_id)
{
int ret;
if (EUCALL_2(Fn_subclassp,classof(pvm_id),Pvm_Id)==nil)
CallError(stacktop,"status: type error",nil,NONCONTINUABLE);
if ((ret = status(PVM_NAME(pvm_id),PVM_NUMBER(pvm_id))) < 0)
CallError(stacktop,"status: call failed",pvm_id,NONCONTINUABLE);
if (ret)
return lisptrue;
else
return nil;
}
EUFUN_CLOSE
/* Message is any sendable object */
static EUFUN_4( Fn_pvm_snd, id, msg_type, msg, reader_maybe)
{
LispObject xx;
#ifdef CGC
unsigned char buf[PVM_MSGBUF];
#else
unsigned char *buf=NULL;
#endif
unsigned char *ptr;
int len;
#ifndef CGC
buf = (unsigned char *)feel_malloc(PVM_MSGBUF);
#endif
ptr = buf;
write_obj(stacktop,msg,&ptr,reader_maybe);
len = ptr - buf;
EUBUG(fprintf(stderr,"Send: %d bytes sent\n",len));
msg_type=ARG_1(stackbase);
if (!is_fixnum(msg_type))
CallError(stacktop,"send: Type error",msg_type,NONCONTINUABLE);
id=ARG_0(stackbase);
initsend();
putnint(&len,1);
putbytes(buf,len);
if (snd(stringof(PVM_NAME(id)),intval(PVM_NUMBER(id)),
intval(msg_type))<0)
CallError(stacktop,"send: call failed",id,NONCONTINUABLE);
#ifndef CGC
feel_free(buf);
#endif
return nil;
}
EUFUN_CLOSE
static EUFUN_3( Fn_pvm_rcv, msg_type, info_p, reader_maybe)
{
static LispObject read_msg(LispObject *, LispObject , LispObject );
if (!is_fixnum(msg_type))
CallError(stacktop,"rcv: type error",msg_type,NONCONTINUABLE);
if (rcv(intval(msg_type)) < 0)
CallError(stacktop,"rcv: call failed",nil,NONCONTINUABLE);
return (read_msg(stacktop,info_p, reader_maybe));
}
EUFUN_CLOSE
EUFUN_3( Fn_pvm_rcvmulti, typelist, info_p, reader_maybe)
{
static LispObject read_msg(LispObject *,LispObject , LispObject );
LispObject ptr;
int len;
len = 0;
ptr = typelist;
while(is_cons(ptr))
{
len++;
ptr = CDR(ptr);
}
{
int buf[len];
int i=0;
ptr=typelist;
while(is_cons(ptr))
{
buf[i]=intval(CAR(ptr));
i++;
ptr=CDR(ptr);
}
if (rcvmulti(len,buf)<0)
CallError(stacktop,"rcvmulti: Call failed",nil,NONCONTINUABLE);
}
return(read_msg(stacktop,info_p, reader_maybe));
}
EUFUN_CLOSE
static LispObject read_msg(LispObject *stacktop,LispObject info_p,LispObject reader_maybe)
{
#ifdef CGC
unsigned char buf[PVM_MSGBUF];
#else
unsigned char *buf=NULL;
#endif
char nam_buf[128];
unsigned char *ptr;
LispObject new_obj;
LispObject sender,result;
int len,inum,type;
if (getnint(&len,1) < 0)
CallError(stacktop,"rcv: getnint call failed",nil,NONCONTINUABLE);
EUBUG(fprintf(stderr,"Rcv: Got %d bytes\n",len));
#ifndef CGC
buf = (unsigned char *)feel_malloc(PVM_MSGBUF);
#endif
ptr = buf;
if (getbytes(buf,len) < 0)
CallError(stacktop,"rcv: getbytes call failed",nil,NONCONTINUABLE);
STACK_TMP(info_p);
new_obj = read_obj(stacktop,&ptr,reader_maybe);
UNSTACK_TMP(info_p);
#ifndef CGC
feel_free(buf);
#endif
EUBUG(fprintf(stderr,"Recv: used %d bytes\n",ptr-buf));
if (info_p!=nil)
{
LispObject xx;
STACK_TMP(new_obj);
rcvinfo(&len,&type,&nam_buf[0],&inum);
xx=allocate_integer(stacktop,type);
xx=EUCALL_2(Fn_cons,xx,nil);
STACK_TMP(xx);
xx=allocate_string(stacktop,nam_buf,strlen(nam_buf));
sender = make_pvm_id(stacktop,xx,inum);
UNSTACK_TMP(xx);
xx=EUCALL_2(Fn_cons,sender,xx);
UNSTACK_TMP(new_obj);
result=EUCALL_2(Fn_cons,new_obj,xx);
return result;
}
else
{
return new_obj;
}
}
/* Readable-p */
static EUFUN_1( Fn_pvm_probe, type)
{
int ret;
if(!is_fixnum(type))
CallError(stacktop,"probe: type error",type,NONCONTINUABLE);
if((ret = probe(intval(type))) < 0)
return nil;
else
return allocate_integer(stacktop,ret);
}
EUFUN_CLOSE
static EUFUN_1( Fn_pvm_probe_multi, typelist)
{
LispObject ptr;
int len,ret;
len = 0;
ptr = typelist;
while(is_cons(ptr))
{
len++;
ptr = CDR(ptr);
}
{
int buf[len];
int i=0;
ptr=typelist;
while(is_cons(ptr))
{
buf[i]=intval(CAR(ptr));
i++;
ptr=CDR(ptr);
}
ret=0;
/*probemulti(len,buf); --- not yet written*/
}
return nil;
}
EUFUN_CLOSE
static EUFUN_2( Fn_pvm_barrier, name, number)
{
if (!is_string(name))
CallError(stacktop,"barrier: type error",name,NONCONTINUABLE);
if (!is_fixnum(number))
CallError(stacktop,"barrier: type error",number,NONCONTINUABLE);
if (barrier(stringof(name),intval(number))<0)
CallError(stacktop,"barrier: call error",number,NONCONTINUABLE);
return nil;
}
EUFUN_CLOSE
static EUFUN_1( Fn_pvm_ready, name) /* simple semaphore */
{
if (!is_string(name))
CallError(stacktop," reader: type error",name,NONCONTINUABLE);
if (ready(stringof(name))<0)
CallError(stacktop," reader: call error",name,NONCONTINUABLE);
return nil;
}
EUFUN_CLOSE
static EUFUN_1( Fn_pvm_waituntil, name)
{
if (!is_string(name))
CallError(stacktop," waituntil: type error",name,NONCONTINUABLE);
if (waituntil(stringof(name))<0)
CallError(stacktop,"waituntil: call error",name,NONCONTINUABLE);
return nil;
}
EUFUN_CLOSE
static EUFUN_0( Fn_pvm_whoami)
{
int ret;
char buf[128];
LispObject xx;
if(whoami(buf,&ret)<0)
CallError(stacktop,"whoami: call error",nil,NONCONTINUABLE);
xx=allocate_string(stacktop,buf,(int) strlen(buf));
return make_pvm_id(stacktop,xx,ret);
}
EUFUN_CLOSE
#define PVM_MODULE_ENTRIES (18)
MODULE Module_pvm;
LispObject Module_pvm_values[PVM_MODULE_ENTRIES];
void INIT_pvm(LispObject *stacktop)
{
extern LispObject Standard_Class,Object, Primitive_Class;
Pvm_Id = allocate_class(stacktop,NULL);
add_root(&Pvm_Id);
make_class(stacktop,Pvm_Id,"pvm-id",Primitive_Class,Object,0);
open_module(stacktop,&Module_pvm,Module_pvm_values,"pvm",
PVM_MODULE_ENTRIES);
(void) make_module_function(stacktop,"make-pvm-id",Fn_make_pvm_id,1);
(void) make_module_function(stacktop,"pvm-status",Fn_pvm_status,1);
(void) make_module_function(stacktop,"pvm-leave",Fn_pvm_leave,0);
(void) make_module_function(stacktop,"pvm-send",Fn_pvm_snd,-4);
(void) make_module_function(stacktop,"pvm-recv",Fn_pvm_rcv,-3);
(void) make_module_function(stacktop,"pvm-recv-multi",Fn_pvm_rcvmulti,-3);
(void) make_module_function(stacktop,"pvm-initiate-by-type",Fn_pvm_initiate_by_type,2);
(void) make_module_function(stacktop,"pvm-initiate-by-hostname",Fn_pvm_initiate_by_host_name,2);
(void) make_module_function(stacktop,"pvm-enroll",Fn_pvm_enroll,1);
(void) make_module_function(stacktop,"pvm-probe",Fn_pvm_probe,1);
(void) make_module_function(stacktop,"pvm-probe-multi",Fn_pvm_probe_multi,1);
(void) make_module_function(stacktop,"pvm-barrier",Fn_pvm_barrier,2);
(void) make_module_function(stacktop,"pvm-ready",Fn_pvm_ready,1);
(void) make_module_function(stacktop,"pvm-waituntil",Fn_pvm_waituntil,2);
(void) make_module_function(stacktop,"pvm-terminate",Fn_pvm_terminate,2);
(void) make_module_function(stacktop,"pvm-whoami",Fn_pvm_whoami,0);
(void) make_module_function(stacktop,"pvm-make-id-from-pair",
Fn_make_pvm_id_from_pair,1);
(void) make_module_entry(stacktop,"pvm-id",Pvm_Id);
close_module();
}